// g++ -o longest_composition -std=c++0x longest_composition.cc

#include <unordered_set>
#include <iostream>
using namespace std;

typedef unordered_set<string> StringSet;

bool contains( const StringSet &words, const string &word ) {
    return words.end() != words.find(word);
}

bool composed( const string & word, const StringSet &words ) {
    for ( string::size_type i = 1, size = word.size(); i < size; i++ ) {
        const string pre = word.substr(0,i);
        const string post = word.substr(i,word.size());
        if ( contains(words, pre) &&
            ( contains( words, post ) || composed( post, words ) ) ) {
            return true;
        }
    }
    return false;
}

string longest_composition( const StringSet &wordset ) {
    string result;
    for ( StringSet::const_iterator it(wordset.begin()), end(wordset.end());
          end != it; it++ ) {
        if ( it->length() > result.length() &&
            composed( *it, wordset ) ) {
            result = *it;
        }
    }
    return result;
}

int main( int argc, char *argv[] ) {
    StringSet words(200000);
#if 1
    ssize_t rlen = 0;
    char *buf = (char*)malloc(1024); // initial size, will realloc
    size_t len = 1024;
    while ( -1 != rlen ) {
        rlen = getline( &buf, &len, stdin );
        // strip any trailing ws
        while (rlen > 0 && isspace(buf[rlen-1])) rlen--;
        if (rlen > 0) {
            string s(buf,buf+rlen);
            words.insert(s);
        }
    }
    free(buf);
#else // this is 4x slower!
    while (!cin.eof()) {
        string word;
        cin >> word;
        cout << word << endl;
        words.insert(word);
    }
#endif
    cout << longest_composition( words ) << endl;
}
